package serial

import (
	"fmt"
	"sync"
	"time"

	"gitee.com/rw555/fdsmastergo/pkg/keypad"
	"gitee.com/rw555/fdsmastergo/pkg/logger"
	"go.uber.org/zap"
)

// SerialDevice 串口设备实现
type SerialDevice struct {
	driver  *Driver
	config  *Config
	mutex   sync.RWMutex
	isReady bool

	// 设备状态缓存
	pumpRunning   bool
	pumpPower     int
	heater1Open   bool
	heater2Open   bool
	ledString     string
	ledDots       int
	ledBrightness int
	ledEnable     bool
	temperature   int
	keyStates     map[keypad.Key]keypad.KeyState

	// 事件处理
	keypadEventChan chan KeypadEvent
	bleEventChan    chan BLEScanResults

	// 事件循环控制
	eventLoopStop chan struct{}
	eventLoopDone chan struct{}

	// 回调函数
	onKeyEvent     func(KeypadEvent)
	onBLEEvent     func(BLEScanResults)
	onStatusChange func(string, interface{})
}

// NewSerialDevice 创建新的串口设备
func NewSerialDevice(config *Config) (*SerialDevice, error) {
	driver, err := NewDriver(config)
	if err != nil {
		return nil, fmt.Errorf("创建串口驱动失败: %w", err)
	}

	device := &SerialDevice{
		driver:          driver,
		config:          config,
		keyStates:       make(map[keypad.Key]keypad.KeyState),
		keypadEventChan: make(chan KeypadEvent, 10),
		bleEventChan:    make(chan BLEScanResults, 10),
		eventLoopStop:   make(chan struct{}),
		eventLoopDone:   make(chan struct{}),
	}

	// 设置驱动回调（不再使用onEventReceived，改用纯通道模式）
	driver.SetStateChangedCallback(device.onStateChanged)
	driver.SetErrorCallback(device.onDriverError)

	return device, nil
}

// Connect 连接设备
func (s *SerialDevice) Connect() error {
	if err := s.driver.Connect(); err != nil {
		return fmt.Errorf("连接串口设备失败: %w", err)
	}

	// 启动统一的事件处理循环
	go s.startEventLoop()

	// 初始化设备状态
	if err := s.initializeDeviceState(); err != nil {
		logger.SystemWarn("初始化设备状态失败", zap.Error(err))
	}

	return nil
}

// Disconnect 断开设备连接
func (s *SerialDevice) Disconnect() error {
	s.mutex.Lock()
	s.isReady = false
	s.mutex.Unlock()

	// 停止事件处理循环
	close(s.eventLoopStop)
	<-s.eventLoopDone // 等待事件循环结束

	return s.driver.Disconnect()
}

// IsConnected 检查设备是否已连接
func (s *SerialDevice) IsConnected() bool {
	return s.driver.IsConnected()
}

// IsReady 检查设备是否就绪
func (s *SerialDevice) IsReady() bool {
	s.mutex.RLock()
	defer s.mutex.RUnlock()
	return s.isReady
}

// 实现 device.Device 接口

// OpenPump 开启水泵
func (s *SerialDevice) OpenPump() error {
	cmd := CreateGPIOSetCommand(1, 1, "out") // 假设引脚1控制水泵

	resp, err := s.driver.SendCommand(cmd)
	if err != nil {
		return fmt.Errorf("发送开启水泵命令失败: %w", err)
	}

	if !resp.IsSuccess() {
		logger.SystemError("水泵开启操作被拒绝",
			zap.String("error", resp.GetErrorMessage()),
			zap.String("status", resp.S))
		return fmt.Errorf("开启水泵失败: %s", resp.GetErrorMessage())
	}

	s.mutex.Lock()
	s.pumpRunning = true
	s.mutex.Unlock()

	logger.SystemInfo("✅ 水泵已开启")
	return nil
}

// ClosePump 关闭水泵
func (s *SerialDevice) ClosePump() error {
	cmd := CreateGPIOSetCommand(1, 0, "out") // 假设引脚1控制水泵
	resp, err := s.driver.SendCommand(cmd)
	if err != nil {
		return fmt.Errorf("发送关闭水泵命令失败: %w", err)
	}

	if !resp.IsSuccess() {
		return fmt.Errorf("关闭水泵失败: %s", resp.GetErrorMessage())
	}

	s.mutex.Lock()
	s.pumpRunning = false
	s.mutex.Unlock()

	logger.SystemInfo("✅ 水泵已关闭")
	return nil
}

// PumpIsRunning 检查水泵是否运行
func (s *SerialDevice) PumpIsRunning() (bool, error) {
	s.mutex.RLock()
	defer s.mutex.RUnlock()
	return s.pumpRunning, nil
}

// SetPumpPower 设置水泵功率
func (s *SerialDevice) SetPumpPower(duty int) error {
	logger.SystemInfo("🔧 设置水泵功率", zap.Int("target_duty", duty))

	if duty < 0 || duty > 100 {
		logger.SystemError("水泵功率值超出范围", zap.Int("duty", duty))
		return fmt.Errorf("功率值必须在0-100之间")
	}

	cmd := CreatePWMSetCommand(1, duty, 1000, duty > 0) // 假设PWM通道1控制水泵功率
	logger.SystemDebug("创建PWM命令",
		zap.String("command_type", string(cmd.C)),
		zap.String("action", string(cmd.A)),
		zap.Any("params", cmd.P))

	resp, err := s.driver.SendCommand(cmd)
	if err != nil {
		logger.SystemError("发送设置水泵功率命令失败", zap.Error(err))
		return fmt.Errorf("发送设置水泵功率命令失败: %w", err)
	}

	if !resp.IsSuccess() {
		logger.SystemError("水泵功率设置被拒绝",
			zap.String("error", resp.GetErrorMessage()),
			zap.String("status", resp.S))
		return fmt.Errorf("设置水泵功率失败: %s", resp.GetErrorMessage())
	}

	s.mutex.Lock()
	s.pumpPower = duty
	s.mutex.Unlock()

	logger.SystemInfo("✅ 水泵功率已设置", zap.Int("duty", duty))
	return nil
}

// GetPumpPower 获取水泵功率
func (s *SerialDevice) GetPumpPower() (int, error) {
	s.mutex.RLock()
	defer s.mutex.RUnlock()
	return s.pumpPower, nil
}

// OpenHeater1 开启加热器1
func (s *SerialDevice) OpenHeater1() error {
	cmd := CreateGPIOSetCommand(2, 1, "out") // 假设引脚2控制加热器1
	resp, err := s.driver.SendCommand(cmd)
	if err != nil {
		return fmt.Errorf("发送开启加热器1命令失败: %w", err)
	}

	if !resp.IsSuccess() {
		return fmt.Errorf("开启加热器1失败: %s", resp.GetErrorMessage())
	}

	s.mutex.Lock()
	s.heater1Open = true
	s.mutex.Unlock()

	logger.SystemInfo("✅ 加热器1已开启")
	return nil
}

// CloseHeater1 关闭加热器1
func (s *SerialDevice) CloseHeater1() error {
	cmd := CreateGPIOSetCommand(2, 0, "out") // 假设引脚2控制加热器1
	resp, err := s.driver.SendCommand(cmd)
	if err != nil {
		return fmt.Errorf("发送关闭加热器1命令失败: %w", err)
	}

	if !resp.IsSuccess() {
		return fmt.Errorf("关闭加热器1失败: %s", resp.GetErrorMessage())
	}

	s.mutex.Lock()
	s.heater1Open = false
	s.mutex.Unlock()

	logger.SystemInfo("✅ 加热器1已关闭")
	return nil
}

// IsHeater1Open 检查加热器1是否开启
func (s *SerialDevice) IsHeater1Open() (bool, error) {
	s.mutex.RLock()
	defer s.mutex.RUnlock()
	return s.heater1Open, nil
}

// OpenHeater2 开启加热器2
func (s *SerialDevice) OpenHeater2() error {
	cmd := CreateGPIOSetCommand(3, 1, "out") // 假设引脚3控制加热器2
	resp, err := s.driver.SendCommand(cmd)
	if err != nil {
		return fmt.Errorf("发送开启加热器2命令失败: %w", err)
	}

	if !resp.IsSuccess() {
		return fmt.Errorf("开启加热器2失败: %s", resp.GetErrorMessage())
	}

	s.mutex.Lock()
	s.heater2Open = true
	s.mutex.Unlock()

	logger.SystemInfo("✅ 加热器2已开启")
	return nil
}

// CloseHeater2 关闭加热器2
func (s *SerialDevice) CloseHeater2() error {
	cmd := CreateGPIOSetCommand(3, 0, "out") // 假设引脚3控制加热器2
	resp, err := s.driver.SendCommand(cmd)
	if err != nil {
		return fmt.Errorf("发送关闭加热器2命令失败: %w", err)
	}

	if !resp.IsSuccess() {
		return fmt.Errorf("关闭加热器2失败: %s", resp.GetErrorMessage())
	}

	s.mutex.Lock()
	s.heater2Open = false
	s.mutex.Unlock()

	logger.SystemInfo("✅ 加热器2已关闭")
	return nil
}

// IsHeater2Open 检查加热器2是否开启
func (s *SerialDevice) IsHeater2Open() (bool, error) {
	s.mutex.RLock()
	defer s.mutex.RUnlock()
	return s.heater2Open, nil
}

// GetTemp 获取温度
func (s *SerialDevice) GetTemp() (int, error) {
	cmd := CreateTempGetCommand()
	resp, err := s.driver.SendCommand(cmd)
	if err != nil {
		return 0, fmt.Errorf("发送获取温度命令失败: %w", err)
	}

	if !resp.IsSuccess() {
		return 0, fmt.Errorf("获取温度失败: %s", resp.GetErrorMessage())
	}

	s.mutex.Lock()
	s.temperature = int(resp.D["value"].(float64))
	s.mutex.Unlock()

	logger.SystemInfo("✅ 温度已获取", zap.Int("temperature", s.temperature))

	return s.temperature, nil
}

// SetLEDString 设置LED字符串
func (s *SerialDevice) SetLEDString(text string, dots int, brightness int, enable bool) error {
	cmd := CreateLEDSetCommand(text, dots, brightness, enable)
	resp, err := s.driver.SendCommand(cmd)
	if err != nil {
		return fmt.Errorf("发送设置LED字符串命令失败: %w", err)
	}

	if !resp.IsSuccess() {
		return fmt.Errorf("设置LED字符串失败: %s", resp.GetErrorMessage())
	}

	s.mutex.Lock()
	s.ledString = text
	s.ledDots = dots
	s.ledBrightness = brightness
	s.ledEnable = enable
	s.mutex.Unlock()

	logger.SystemInfo("✅ LED字符串已设置")
	return nil
}

// GetLEDString 获取LED字符串
func (s *SerialDevice) GetLEDParams() (string, int, int, bool) {
	s.mutex.RLock()
	defer s.mutex.RUnlock()
	return s.ledString, s.ledDots, s.ledBrightness, s.ledEnable
}

// GetKeyState 获取按键状态
func (s *SerialDevice) GetKeyState(key keypad.Key) (keypad.KeyState, error) {
	s.mutex.RLock()
	defer s.mutex.RUnlock()

	if state, exists := s.keyStates[key]; exists {
		return state, nil
	}

	return keypad.KeyReleased, nil
}

// AsKeypad 返回按键接口
func (s *SerialDevice) AsKeypad() keypad.Keypad {
	return &serialKeypad{device: s}
}

// SetBLEScanning 设置BLE扫描
func (s *SerialDevice) SetBLEScanning(enable bool, filterName string) error {
	logger.SystemInfo("🔧 设置BLE扫描",
		zap.Bool("enable", enable),
		zap.String("filter", filterName))

	cmd := CreateBLESetCommand(enable, filterName)
	logger.SystemDebug("创建BLE命令",
		zap.String("command_type", string(cmd.C)),
		zap.String("action", string(cmd.A)),
		zap.Any("params", cmd.P))

	resp, err := s.driver.SendCommand(cmd)
	if err != nil {
		logger.SystemError("发送BLE扫描命令失败", zap.Error(err))
		return fmt.Errorf("设置BLE扫描失败: %w", err)
	}

	if !resp.IsSuccess() {
		logger.SystemError("BLE扫描设置被拒绝",
			zap.String("error", resp.GetErrorMessage()),
			zap.String("status", resp.S))
		return fmt.Errorf("设置BLE扫描失败: %s", resp.GetErrorMessage())
	}

	status := "已停止"
	if enable {
		status = "已启动"
	}
	logger.SystemInfo("✅ BLE扫描"+status, zap.String("filter", filterName))
	return nil
}

// SetKeyEventCallback 设置按键事件回调
func (s *SerialDevice) SetKeyEventCallback(callback func(KeypadEvent)) {
	s.onKeyEvent = callback
}

// SetBLEEventCallback 设置BLE事件回调
func (s *SerialDevice) SetBLEEventCallback(callback func(BLEScanResults)) {
	s.onBLEEvent = callback
}

// SetStatusChangeCallback 设置状态变化回调
func (s *SerialDevice) SetStatusChangeCallback(callback func(string, interface{})) {
	s.onStatusChange = callback
}

// 内部方法

// initializeDeviceState 初始化设备状态
func (s *SerialDevice) initializeDeviceState() error {
	// 查询各个设备的初始状态
	// 这里可以发送查询命令获取设备的真实状态

	s.mutex.Lock()
	defer s.mutex.Unlock()

	// 初始化默认状态
	s.pumpRunning = false
	s.pumpPower = 0
	s.heater1Open = false
	s.heater2Open = false
	s.temperature = 0
	s.isReady = true

	return nil
}

// onStateChanged 状态变化回调
func (s *SerialDevice) onStateChanged(state ConnectionState) {
	s.mutex.Lock()
	s.isReady = (state == StateConnected)
	s.mutex.Unlock()

	if s.onStatusChange != nil {
		s.onStatusChange("connection_state", state.String())
	}
}

// onDriverError 驱动错误回调
func (s *SerialDevice) onDriverError(err error) {
	logger.SystemError("串口设备驱动错误", zap.Error(err))

	if s.onStatusChange != nil {
		s.onStatusChange("driver_error", err.Error())
	}
}

// handleKeyEvent 处理按键事件
func (s *SerialDevice) handleKeyEvent(event *Event) {
	keyEvent, err := event.ParseKeyEvent()
	if err != nil {
		logger.SystemError("解析按键事件失败", zap.Error(err))
		return
	}

	// 转换为keypad事件
	key := parseKeyFromString(keyEvent.Key)
	eventType := parseEventTypeFromString(keyEvent.Event)

	// 更新按键状态
	s.mutex.Lock()
	s.keyStates[key] = keypadStateFromEventType(eventType)
	s.mutex.Unlock()

	// 创建keypad事件
	kEvent := KeypadEvent{
		Key:       key,
		Type:      eventType,
		Timestamp: time.Unix(keyEvent.Timestamp/1000, 0),
	}

	// 统一通道模式：发送到内部事件通道
	select {
	case s.keypadEventChan <- kEvent:
		logger.SystemDebug("按键事件已发送到内部通道")
	default:
		logger.SystemWarn("按键事件通道已满，丢弃事件")
	}
}

// handleBLEEvent 处理BLE事件
func (s *SerialDevice) handleBLEEvent(event *Event) {
	bleResults, err := event.ParseBLEScanResults()
	if err != nil {
		logger.SystemError("解析BLE扫描结果失败", zap.Error(err))
		return
	}

	// 统一通道模式：只发送到事件通道，由eventLoop统一处理
	select {
	case s.bleEventChan <- *bleResults:
		logger.SystemDebug("BLE事件已发送到内部通道")
	default:
		logger.SystemWarn("BLE事件通道已满，丢弃事件")
	}
}

// serialKeypad 串口设备的按键接口实现
type serialKeypad struct {
	device *SerialDevice
}

// GetEventChannel 获取按键事件通道
func (sk *serialKeypad) GetEventChannel() <-chan KeypadEvent {
	return sk.device.keypadEventChan
}

// IsPressed 检查按键是否被按下
func (sk *serialKeypad) IsPressed(key keypad.Key) bool {
	state, _ := sk.device.GetKeyState(key)
	return state == keypad.KeyPressed
}

// GetState 获取按键状态
func (sk *serialKeypad) GetState(key keypad.Key) keypad.KeyState {
	state, _ := sk.device.GetKeyState(key)
	return state
}

// GetKeyState 实现keypad.Keypad接口
func (sk *serialKeypad) GetKeyState(key keypad.Key) (keypad.KeyState, error) {
	return sk.device.GetKeyState(key)
}

// startEventLoop 启动统一的事件处理循环
func (s *SerialDevice) startEventLoop() {
	defer close(s.eventLoopDone)

	logger.SystemDebug("🔄 启动统一事件处理循环")

	// 获取驱动层的事件通道
	driverEventChan := s.driver.GetEventChannel()

	for {
		select {
		case <-s.eventLoopStop:
			logger.SystemInfo("🔄 事件处理循环收到停止信号")
			return

		// 处理来自驱动层的事件（通过通道）
		case event := <-driverEventChan:
			if event != nil {
				s.handleDriverEvent(event)
			}

		// 处理内部按键事件（发送给应用层）
		case keyEvent := <-s.keypadEventChan:
			if s.onKeyEvent != nil {
				s.onKeyEvent(keyEvent)
			}

		// 处理内部BLE事件（发送给应用层）
		case bleEvent := <-s.bleEventChan:
			if s.onBLEEvent != nil {
				s.onBLEEvent(bleEvent)
			}
		}
	}
}

// handleDriverEvent 处理来自驱动层的事件
func (s *SerialDevice) handleDriverEvent(event *Event) {
	logger.SystemDebug("🎯 统一事件处理",
		zap.String("event_type", string(event.Type)))

	switch event.Type {
	case EventTypeAdcKeyEvent:
		s.handleKeyEvent(event)
	case EventTypeBLEScanResults:
		s.handleBLEEvent(event)
	default:
		logger.SystemWarn("未知事件类型",
			zap.String("event_type", string(event.Type)))
	}
}
